﻿using Script.Structs.Pawn;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DesignerScripts;
using Game;
using Game.UI;
using Script.Game;
using UnityEngine;
using ZYLFramework.Manage;

public class LevelManager : MonoBehaviour
{
    /// <summary>
    /// 地图实列化基础点
    /// </summary>
    private GameObject Root;
    /// <summary>
    /// 辅助清除表
    /// </summary>
    private GameObject[] Mt;
    /// <summary>
    /// 棋子回收池
    /// </summary>
    private List<GameObject> PawnRecyclePool;

    /// <summary>
    /// 关卡实例
    /// </summary>
    private LevelInfoObj LevelInfoObj;
    
    /// <summary>
    /// 选中的棋子
    /// </summary>
    public GameObject SelectPawn;

    /// <summary>
    /// 
    /// </summary>
    public PawnActionScripts PawnActionScripts;
    
    /// <summary>
    /// 是否修改了对局状态
    /// </summary>
    public bool IsModRoundState = false;

    /// <summary>
    /// 创建关卡
    /// </summary>
    void CreateLevel(CreateLevelInfo createLevelInfo)
    {
        LevelInfoObj.Init();
        // 设置地图
        var mapInfoModel = DesignerTables.MapInfo.data[createLevelInfo.Model.MapId];
        var GridMap = new GridInfo[mapInfoModel.MapSize[0],mapInfoModel.MapSize[1]];
        for (int i = 0; i < mapInfoModel.MapSize[0];i++)
        {
            for (int j = 0; j < mapInfoModel.MapSize[1]; j++)
            {
                GridMap[i, j] = DesignerTables.MapInfo.MapType[mapInfoModel.Grid[i, j]];
            } 
        }
        LevelInfoObj.MapInfo = new MapInfo(GridMap, Vector2.one);
        GameState.MapGameObjects = new GameObject[mapInfoModel.MapSize[0], mapInfoModel.MapSize[1]];
        CreateMapGameObjects(LevelInfoObj.MapInfo,ref GameState.MapGameObjects);

        // 设置阵营和棋子的映射关系
        foreach (var pawnInfo in createLevelInfo.Model.PawnInfoList)
        {
            var pawn = CreatePawn(pawnInfo);
            var pawnState = pawn.GetComponent<PawnState>();
            if (!LevelInfoObj.CampPawnDict.ContainsKey(pawnState.CampId))
            {
                LevelInfoObj.CampPawnDict[pawnState.CampId] = new List<GameObject>();
            }
            LevelInfoObj.CampPawnDict[pawnState.CampId].Add(pawn);
            AddPawn(new Vector2Int(pawnInfo.Pos[0],pawnInfo.Pos[1]),pawn);
        }

        // 设置阵营数据
        List<CampInfoModel> campInfoModels = new List<CampInfoModel>();
        foreach (var v in LevelInfoObj.CampPawnDict)
        {
            campInfoModels.Add(DesignerTables.CompInfo.data[v.Key]);
        }
        // 按照阵营权限排序下
        campInfoModels.Sort((x, y) => x.Priority.CompareTo(y.Priority));
        LevelInfoObj.CampInfoObj = new CampInfoObj(campInfoModels.ToArray());
        LevelInfoObj.CurActionCamp = campInfoModels[0].Id;

        // 设置剧本数据
        foreach (var addScreenplayInfo in createLevelInfo.Model.AddScreenplayList)
        {
            LevelInfoObj.ScreenplayObjs.Add(new ScreenplayObj(
                DesignerTables.Screenplay.data[addScreenplayInfo.ScreenplayId],
                addScreenplayInfo.Duration,
                addScreenplayInfo.Permanent));
        }
        LevelInfoObj.ScreenplayObjs.Sort((a, b)=>{
            return a.Model.Priority.CompareTo(b.Model.Priority);
        });

        GameState.CurRoundState = LevelInfoObj.RoundState;
        IsModRoundState = false;
        LevelInfoObj.LevelOver = false;
    }
    // Start is called before the first frame update
    void Awake()
    {
        Root = GameObject.Find("Root");
        // PawnRecyclePool = new List<GameObject>();
        LevelInfoObj = LevelInfoObj.Zero;
        PawnActionScripts = new PawnActionScripts();
    }

    /// <summary>
    /// 关卡结束处理
    /// </summary>
    public void EndOfLevel(bool winFlag)
    {
        LevelInfoObj.LevelOver = true;
        LevelInfoObj.WinFlag = winFlag;
        GameState.CurRoundState = RoundState.Wait;

        var winStr = LevelInfoObj.WinFlag ? "胜利" : "失败";
        
        List<TimelineNode> timelineNodes = new List<TimelineNode>();
        float time = 0;
        time += 1f;
        timelineNodes.Add(new TimelineNode(time,"OpenUI",UIEnum.RoundPanel));
        time += 0.1f;
        timelineNodes.Add(new TimelineNode(time,"UINotifyMessageEvent",EventEnum.SetRoundText,"关卡结束"));
        time += 0.5f;
        timelineNodes.Add(new TimelineNode(time,"UINotifyMessageEvent",EventEnum.SetRoundText,winStr));
        time += 0.5f;
        timelineNodes.Add(new TimelineNode(time,"CloseUI"));
        time += 0.1f;
        timelineNodes.Add(new TimelineNode(time,"UINotifyMessageEvent",EventEnum.SetOverWinText,winStr));
        time += 0.1f;
        timelineNodes.Add(new TimelineNode(time,"OpenUI",UIEnum.OverPanel));
        TimelineModel timelineModel = new TimelineModel("", timelineNodes.ToArray(), time, TimelineGoTo.Null);
        SceneVariants.CreateTimeline(timelineModel, this.gameObject, null); 
    }

    /// <summary>
    /// 每回合做什么的回调点
    /// </summary>
    void ScreenplayOnRoundTick()
    {
        if (LevelInfoObj.LevelOver)
        {
            return;
        }

        var ScreenplayObjs = LevelInfoObj.ScreenplayObjs;
        List<ScreenplayObj> toRemove = new List<ScreenplayObj>();
        for (int i = 0; i < ScreenplayObjs.Count; i++)
        {
            if (!ScreenplayObjs[i].Permanent)
            {
                ScreenplayObjs[i].Duration -= 1;
            }

            ScreenplayObjs[i].TimeElapsed += 1;

            if (ScreenplayObjs[i].Model.OnRoundTick != null)
            {
                ScreenplayObjs[i].Model.OnRoundTick(ScreenplayObjs[i]);
                ScreenplayObjs[i].Ticked += 1;
            }

            if (ScreenplayObjs[i].Duration <= 0)
            {
                toRemove.Add(ScreenplayObjs[i]);
            }
        }
        
        if (toRemove.Count > 0){
            for (int i = 0; i < toRemove.Count; i++){
                LevelInfoObj.ScreenplayObjs.Remove(toRemove[i]);
            }
        }
        toRemove = null;
    }
    
    void Start()
    {
    }
    
    void Update()
    {
    }
    
    void FixedUpdate()
    {
        StartCoroutine(PringDebugLog());
        SwitchGameState();
    }
    
    /// <summary>
    /// 切换游戏状态
    /// </summary>
    /// <returns></returns>
    void SwitchGameState()
    {
        //如果对局状态没有修改
        if (!IsModRoundState)
        {
            return;
        }
        IsModRoundState = false;
        switch (GameState.CurRoundState)
        {
            case RoundState.Start:
                StartCompRound();
                break;
            case RoundState.PawnAction:
                PawnActionRound();
                break;
            case RoundState.Over:
                OverCurCompRound();
                break;
        }
    }
    
    IEnumerator PringDebugLog()
    {
        var canAction = "";
        if (SelectPawn)
        {
            var dictionary = SelectPawn.GetComponent<PawnState>().ControlState.GetActionList();
            foreach (ActionType key in dictionary.Keys)
            {
                canAction +="|"+ key.ToString();
            }
        }
        string str = $"当前阵营:{LevelInfoObj.CurActionCamp}\n" +
                     $"当前回合:{LevelInfoObj.RoundsNum}\n" +
                     $"当前回合状态:{GameState.CurRoundState.ToString()}\n" +
                     $"当前角色:{SelectPawn}\n" +
                     $"当前角色可进行的行动:{canAction}\n" +
                     $"当前光标位置:{GameState.FocusPos}\n" +
                     $"over";
                     
        SceneVariants.NotifyMessageEvent(EventEnum.SetDebugInfo,str);
        yield return new WaitForSeconds(1f);
    }
    
    //加载关卡
    public void LoadLevel(int levelId)
    {
        ResetLevel();
        CreateLevel(new CreateLevelInfo(DesignerTables.Level.data["Test"]));
        //开始回合
        SetRoundState(RoundState.Start);
    }
    
    //退出关卡
    private void ResetLevel()
    {
        // 清除棋子的信息
        if (LevelInfoObj.CampInfoObj != null)
        {
            foreach (var InfoModel in LevelInfoObj.CampInfoObj.Models)
            {
                foreach (var go in LevelInfoObj.CampPawnDict[InfoModel.Id])
                {
                    if (go != null)
                    {
                        ClearPawn(go);
                        Destroy(go);
                    }
                } 
            } 
        } 
        // 清除gameState的信息
        GameState.ResetInfo();
    }
    
    /// <summary>
    /// 检查一个阵营是否还有存活的单位
    /// </summary>
    /// <param name="comp"></param>
    /// <returns>true 存在存活的单位</returns>
    public bool CheckCompPawnSurvival(string camp)
    {
        if (LevelInfoObj.CampPawnDict.ContainsKey(camp))
        {
            foreach (var go in LevelInfoObj.CampPawnDict[camp])
            {
                if (go != null)
                {
                    var pawnState = go.GetComponent<PawnState>();
                    if (pawnState !=null && !pawnState.dead)
                    {
                        return true;
                    }
                }
            } 
        }
        return false;
    }
    
    /// <summary>
    /// 检查一个阵营是否还有没有行动的单位
    /// </summary>
    /// <param name="camp"></param>
    /// <returns>true 存在可以行动的单位</returns>
    private bool CheckCompPawnAction(string camp)
    {
        if (LevelInfoObj.CampPawnDict.ContainsKey(camp))
        {
            foreach (var go in LevelInfoObj.CampPawnDict[camp])
            {
                if (go != null)
                {
                    var pawnState = go.GetComponent<PawnState>();
                    if (pawnState !=null && !pawnState.dead && pawnState.ControlState.CanAction())
                    {
                        return true;
                    }
                }
            } 
        }
        return false;
    }
    
    //根据单元格坐标获取地图坐标
    public Vector3 GetPosByGridPos(int gridX,int gridY)
    {
        return LevelInfoObj.MapInfo.GetPosByGridPos(gridX, gridY);
    }
    
    //根据单元格坐标获取地图坐标
    public Vector3 GetPosByGridPos(Vector2Int gridXY,bool isCheck = true)
    {
        return isCheck?LevelInfoObj.MapInfo.GetPosByGridPos(gridXY.x,gridXY.y):LevelInfoObj.MapInfo.GetPosByGridPosNoCheck(gridXY.x,gridXY.y);
    }
    
    /// 获取地图边缘
    public Vector3 GetPosByGameState()
    {
        return GetPosByGridPos(new Vector2Int(LevelInfoObj.MapInfo.MapWidth(),LevelInfoObj.MapInfo.MapHeight()),false);
    }
    
    /// <summary>
    /// 尝试自动结束回合
    /// </summary>
    public void AutoOverCompRound()
    {
        if (!CheckCompPawnAction(LevelInfoObj.CurActionCamp))
        {
            SetRoundState(RoundState.Over);
        }
    }
    
    //设置回合状态
    public void SetRoundState(RoundState roundState)
    {
        Debug.Log(GameState.CurRoundState);
        if (roundState == GameState.CurRoundState)
        {
            return;
        }
        GameState.CurRoundState = roundState;
        SetPlayerInputState(roundState);
        IsModRoundState = true;
    }
    
    //设置玩家输入状态
    public void SetPlayerInputState(RoundState roundState)
    {
        SceneVariants.GetGameManager().SetAcceptInput(roundState == RoundState.PawnAction && "Player" == LevelInfoObj.CurActionCamp);
    }
    
    ///开始阵营的回合
    private void StartCompRound()
    {
        if (LevelInfoObj.LevelOver)
        {
            return;
        }
        List<string> ShowTextList = new List<string>();
        // 如果回到玩家阵营开始就+1回合数
        if ("Player" == LevelInfoObj.CurActionCamp)
        {
            LevelInfoObj.RoundsNum += 1;
            // 播放开幕
            Debug.Log($"第{LevelInfoObj.RoundsNum}回合");
            ShowTextList.Add($"第{LevelInfoObj.RoundsNum}回合开始");
            //触发aoe事件
            //触发回合脚本
            ScreenplayOnRoundTick();
        }
        
        foreach (var pawn in LevelInfoObj.CampPawnDict[LevelInfoObj.CurActionCamp])
        {
            // if (Object.IsNull(gameObject))
            // {
            //     
            // }
            pawn?.GetComponent<PawnState>().ControlState.Origin();
        }
        //触发阵营回合脚本
        foreach (var t in LevelInfoObj.ScreenplayObjs)
        {
            t.Model.OnCompRoundTick?.Invoke(t);
        } 
        // 遍历执行buff
        Debug.Log($"结算buff");
        ShowTextList.Add($"轮到{LevelInfoObj.CampInfoObj.Dict[LevelInfoObj.CurActionCamp].Name}阵营行动");

        // 播放开幕
        RoundStartShow(new RoundShowInfo(ShowTextList.ToArray(),null));
    }
    
    /// <summary>
    /// 选择棋子状态
    /// </summary> 
    public void Submit(Vector2Int cursorPos,ActionType actionType = ActionType.select)
    {
        if (LevelInfoObj.LevelOver)
        {
            return;
        }

        if (SelectPawn == null)
        {
            actionType = ActionType.select;
        }
        else
        {
            actionType = SelectPawn.GetComponent<PawnState>().ControlState.DefaultAction;
        }
        
        PawnActionScripts.Func[actionType](new ActionInfo(
            cursorPos,
            SelectPawn,
            LevelInfoObj
            ));
    }

    /// <summary>
    /// 判断这个坐标是否在地图内
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public bool CheckGridInPosition(Vector2 pos)
    {
        return LevelInfoObj.MapInfo.CheckGridInPosition(pos);
    }
    
    /// <summary>
    /// 根据坐标销毁一个棋子
    /// </summary>
    void ClearPawn(Vector2Int pos)
    {

        ClearPawn(pos, GameState.Pos2PawnDict[pos]);
    } 
    /// <summary>
    /// 根据棋子销毁一个棋子
    /// </summary>
    public void ClearPawn(GameObject pawn)
    {
        if (GameState.Pawn2PosDict.ContainsKey(pawn))
        {
           ClearPawn(GameState.Pawn2PosDict[pawn],pawn); 
        }
    } 
    
    /// <summary>
    /// 销毁一个棋子
    /// </summary>
    void ClearPawn(Vector2Int pos,GameObject pawn)
    {

        GameState.Pawn2PosDict.Remove(pawn); 
        GameState.Pos2PawnDict.Remove(pos);
        SceneVariants.NotifyMessageEvent(EventEnum.RemovePawnState,pawn);
    } 
    
    /// <summary>
    /// 添加一个棋子
    /// </summary>
    public void AddPawn(Vector2Int pos,GameObject pawn)
    {
        GameState.Pawn2PosDict.Add(pawn,pos); 
        GameState.Pos2PawnDict.Add(pos,pawn); 
        SceneVariants.NotifyMessageEvent(EventEnum.AddPawnState,pawn);
    }
    
    /// <summary>
    /// 棋子行动完成
    /// </summary>
    public void PawnActionOver()
    {
        AutoOverCompRound();
        SelectPawn = null;
    }
    
    /// <summary>
    /// 执行操作
    /// </summary>
    private void PawnActionRound()
    {
        if (LevelInfoObj.LevelOver)
        {
            return;
        }
        // 如果都死完了的话就直接回合结束
        if (!CheckCompPawnSurvival(LevelInfoObj.CurActionCamp))
        {
            SetRoundState(RoundState.Over);
        }
        
        if (LevelInfoObj.IsAIControl())
        {
            SetRoundState(RoundState.Over);  
        }
    }
    
    /// <summary>
    /// 结束阵营行动
    /// </summary>
    private void OverCurCompRound()
    {
        if (LevelInfoObj.LevelOver)
        {
            return;
        }
        SetNextComp();
        RoundOverShow(new RoundShowInfo(new []{$"行动结束"},null));
    }
    
    /// <summary>
    /// 回合开始显示处理
    /// </summary>
    public void RoundStartShow(RoundShowInfo roundShowInfo)
    {
        List<TimelineNode> timelineNodes = new List<TimelineNode>();
        float time = 0;
        if (roundShowInfo.ShowText != null)
        {
            time += 1f;
            timelineNodes.Add(new TimelineNode(time,"OpenUI",UIEnum.RoundPanel));
            time += 0.1f;
            foreach (var str in roundShowInfo.ShowText)
            {
                timelineNodes.Add(new TimelineNode(time,"UINotifyMessageEvent",EventEnum.SetRoundText,str));
                time += 0.5f;
            }

            timelineNodes.Add(new TimelineNode(time,"CloseUI"));
            time += 0.1f;
            timelineNodes.Add(new TimelineNode(time,"OpenUI",UIEnum.PawnStatePanel));
        }
        
        if (roundShowInfo.MapShowInfos != null)
        {
            
        }
        timelineNodes.Add(new TimelineNode(time,"SetRoundState",RoundState.PawnAction));
        TimelineModel timelineModel = new TimelineModel("", timelineNodes.ToArray(), time, TimelineGoTo.Null);
        SceneVariants.CreateTimeline(timelineModel, this.gameObject, null); 
    }
    
    /// <summary>
    /// 回合结束显示处理
    /// </summary>
    public void RoundOverShow(RoundShowInfo roundShowInfo)
    {
        List<TimelineNode> timelineNodes = new List<TimelineNode>();
        float time = 0;
        if (roundShowInfo.ShowText != null)
        {
            time += 1f;
            timelineNodes.Add(new TimelineNode(time,"OpenUI",UIEnum.RoundPanel));
            time += 0.1f;
            foreach (var str in roundShowInfo.ShowText)
            {
                timelineNodes.Add(new TimelineNode(time,"UINotifyMessageEvent",EventEnum.SetRoundText,str));
                time += 0.5f;
            }

            timelineNodes.Add(new TimelineNode(time,"CloseUI"));
            time += 0.1f;
            timelineNodes.Add(new TimelineNode(time,"OpenUI",UIEnum.PawnStatePanel));
        }
        
        timelineNodes.Add(new TimelineNode(time,"SetRoundState",RoundState.Start));
        TimelineModel timelineModel = new TimelineModel("", timelineNodes.ToArray(), time, TimelineGoTo.Null);
        SceneVariants.CreateTimeline(timelineModel, this.gameObject, null); 
    }
    
    /// <summary>
    /// 获取下一个行动的阵营
    /// </summary>
    public void SetNextComp()
    {
        LevelInfoObj.CurActionCamp = LevelInfoObj.CampInfoObj.GetNextCamp(LevelInfoObj.CurActionCamp);
    }
    
    //根据关卡map制作地图的prefabs
    private void CreateMapGameObjects(MapInfo map,ref GameObject[,] MapGO){
        Mt = GameObject.FindGameObjectsWithTag("MapTile");
        for (var i = 0; i < Mt.Length; i++){
            Destroy(Mt[i]);
        }
        Mt = null;
        for (var j = 0; j < map.MapHeight(); j++){
            for (var i = 0; i < map.MapWidth(); i++)
            {
                var temp = CreateFromPrefab("Map/"+map.Grid[i,j].PrefabPath, GetPosByGridPos(i,j));
                temp.GetComponent<BaseMap>().SetHighlightVisible(false);
                MapGO[i,j] = temp;
            }
        }
    }

    ///<summary>
    /// 回收棋子
    ///<param name="pawn">游戏棋子对象</param>
    ///</summary>
    public void RecyclePawn(GameObject pawn)
    {
        if (pawn.GetComponent<PawnState>()==null)
        {
           return;
        }

        //触发杀死棋子的回合脚本
        foreach (var t in LevelInfoObj.ScreenplayObjs)
        {
            t.Model.OnKillPawn?.Invoke(t);
        } 
        pawn.transform.position = new Vector3(99999, 99999, -99999);
        // PawnRecyclePool.Add(pawn);
    }

    //根据prefab下的资源创建东西
    private GameObject CreateFromPrefab(string prefabPath, Vector3 position = new Vector3(), float rotation = 0.00f){
        GameObject go = Instantiate<GameObject>(
            Resources.Load<GameObject>("Prefabs/" + prefabPath),
            position,
            Quaternion.identity
        );
        if (rotation != 0){
            go.transform.Rotate(new Vector3(0, rotation, 0));
        }
        go.transform.SetParent(Root.transform);
        return go;
    }
    
    /// <summary>
    /// 根据创建信息创建棋子
    /// </summary>
    /// <param name="levelPawnInfo"></param>
    /// <returns></returns>
    private GameObject CreatePawn(LevelPawnInfo levelPawnInfo){
        GameObject pawnObj;
        // if (PawnRecyclePool.Count > 0)
        // {
        //     pawnObj = PawnRecyclePool[0];
        //     PawnRecyclePool.RemoveAt(0);
        // }
        // else
        // {
        //     pawnObj = CreateFromPrefab("Pawn/Pawn1");
        // }
        
        var pawnData = DesignerTables.Pawn.data[levelPawnInfo.PawnId];
        pawnObj = CreateFromPrefab(pawnData.AssetsPath);
        PawnState ps = pawnObj.GetComponent<PawnState>();
        if (ps)
        {
            // var pawnData = DesignerTables.Pawn.data[levelPawnInfo.PawnId];
            ps.InitBaseProp(pawnData.PawnProperty);
            // ps.SetGuise(pawnData.AssetsPath);
            ps.SetCamp(levelPawnInfo.CampId,DesignerTables.CompInfo.data[levelPawnInfo.CampId].Color);
        }

        var pawnPos = GetPosByGridPos(levelPawnInfo.Pos[0],levelPawnInfo.Pos[1]);
        //深度特殊处理
        pawnPos.z = -5;
        pawnObj.transform.position = pawnPos;
        return pawnObj;
    }
}
